package com.fingard.dsp.bank.directbank.bbg02;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.util.SmbFileUtil;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.sql.Connection;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

import static com.fingard.text.StringHelper.trimEndFileSp;

/**
 * Created by F on 2019/02/26.
 */
public class BBG02BatPayRec extends BBG02Base implements IBatPayRec {

//    private static final String INSERTSEQ = "INSERT INTO REQSEQIDMAPPING(URID,BANKCODE,TRANSDATE,REQSEQID,BANKREQSEQID) values (?,?,?,?,?);";
//    private static final String SELECTSEQ = "SELECT BANKREQSEQID FROM REQSEQIDMAPPING WHERE REQSEQID=?;";

    /**
     * 批量代付提交
     *
     * @param p_req1988
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        //返回ATS的对象
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req1988.reqHeader);
        Connection conn = FGBiz.getLocalDbConn();
        try {
            //拼接请求报文头
            XmlTextWriter xmlTextWriter = new XmlTextWriter();
            BBG02Header header = new BBG02Header();
            header.tr_code = "300002";
            header.req_no = p_req1988.reqBatchNO;
            header.file_flag = "1";
            writeCommonHeader(xmlTextWriter, header);
            xmlTextWriter.writeEndElement();
            //拼接请求报文体
            XElement body = new XElement("body", "");
            body.addChild(new XElement("batch_no", p_req1988.reqBatchNO));//批次号
            body.addChild(new XElement("pay_acno", p_req1988.ownAct));//付款账号
            body.addChild(new XElement("pay_cur_code", convertCurToBank(p_req1988.ownCur)));//付款币种
            body.addChild(new XElement("pay_acname", p_req1988.ownActName));//付款户名
            body.addChild(new XElement("as_flag", "0"));//是否使用账簿号 0：不需要 1：需
            body.addChild(new XElement("as_acno", ""));//账簿号
            body.addChild(new XElement("supply_item", "0001"));//项目编号 0001代发工资
            body.addChild(new XElement("amt", p_req1988.totalAmt));//总交易金额
            body.addChild(new XElement("count", p_req1988.totalNum));//总笔数
            body.addChild(new XElement("purpose", ""));//用途
            body.addChild(new XElement("postscript", p_req1988.useType));//附言
            //拼接批付数据到文件
            String fileName = p_req1988.reqBatchNO + ".txt";
            String filePath = StringHelper.trimEnd(FGBiz.dspCenter.dspSet.dataDirPath, "/") + File.separator + p_req1988.reqHeader.bankCode
                    + File.separator + Format.Date8Format.format(new Date());
            if (!FileHelper.existFile(filePath)) {
                FileHelper.mkdir(filePath);
            }
            int tmpCount = 0;
            StringBuilder sb = new StringBuilder("acno|cur_code|acname|cardflag|amt|postscript|").append("\r\n");
            while (p_req1988.readRecord()) {
                tmpCount++;
                //账号|币种|户名|卡折标志（0-卡  1-折）|金额|附言|
                sb.append(p_req1988.readedDetail.recAct).append("|").append(convertCurToBank(p_req1988.readedDetail.recCur)).append("|")
                        .append(p_req1988.readedDetail.recName).append("|").append(" ").append("|")
                        .append(p_req1988.readedDetail.payAmount).append("|").append(p_req1988.readedDetail.askNumber).append("|");
                if (tmpCount != Integer.parseInt(p_req1988.totalNum)) {
                    sb.append("\r\n");
                }
            }
            String fileNamePath = filePath + File.separator + fileName;
            FileHelper.writeFile(fileNamePath, sb);
            //上传文件到前置机目录
            if (FileHelper.existFile(fileNamePath)) {
                int result = SmbFileUtil.smbUploading(fileNamePath, "", bankFront.bkTransFolder);
                if (result == -1) {
                    retAts.respCode = "-1";
                    retAts.respInfo = "上传文件到前置机目录异常";
                    retAts.writeRetToATS();
                    return retAts;
                }
            }
            body.addChild(new XElement("file_name", fileName));//文件名
            if (tmpCount != Integer.parseInt(p_req1988.totalNum)) {
                retAts.respCode = "-1";
                retAts.respInfo = "写入数据异常";
                retAts.writeRetToATS();
                return retAts;
            }
            xmlTextWriter.writeXElement(body);
            xmlTextWriter.writeEndDocument();
            //发送请求报文
            String[] bankResult = sendToBank(xmlTextWriter.toXmlString(), p_req1988.reqHeader.transType, p_req1988.reqHeader.commandCode);
            if (bankResult[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader xmlSbReader = loadBankRespXmlReader(bankResult[1].substring(bankResult[1].indexOf("<ap>")), tmpSbMsg);
                if (xmlSbReader != null) {
//                    String serial_no= xmlSbReader.getFirstText("/ap/head/serial_no");
                    String respCode = "0000".equals(xmlSbReader.getFirstText("/ap/head/ret_code")) ? "0000" : "others";//都是支付中
                    String respInfo = xmlSbReader.getFirstText("/ap/head/ret_info");
                    String errorInfo = xmlSbReader.getFirstText("/ap/head/ext_info");
                    retAts.respCode = "0";
                    retAts.respInfo = respInfo + "：" + errorInfo;
                    retAts.reqSeqID = p_req1988.reqBatchNO;
                    retAts.payInfoCode = respCode;
                    retAts.transState = retAts.payInfoCode;
                    //记录批次号对应的银行支付流水号，供查询状态接口使用
//                    String uuid = UUID.randomUUID().toString().replaceAll("-", "");
//                    JDBCHelper.update(conn, INSERTSEQ, new Object[]{uuid, p_req1988.reqHeader.bankCode, Format.Date8Format.format(new Date()), p_req1988.reqBatchNO, serial_no});
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            } else if (bankResult[0].equals(ConnState.FAIL)) {
                retAts.respCode = "0";
                retAts.respInfo = bankResult[1];
                retAts.reqSeqID = p_req1988.reqBatchNO;
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = bankResult[0];
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = bankResult[1];
            }
        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.toString();
            WriteBankLogLn("批量代发异常：" + e);
            e.printStackTrace();
        } finally {
            conn.close();
        }
        if (retAts.respCode.equals("-1") && StringHelper.isNullOrEmpty(retAts.reqSeqID)) {
            retAts.reqSeqID = p_req1988.reqBatchNO;
        }
        retAts.writeRetToATS();
        return retAts;
    }

    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        // 返回ATS的对象
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
        Connection conn = FGBiz.getLocalDbConn();
        try {
            //拼接请求报文头
            XmlTextWriter xmlTextWriter = new XmlTextWriter();
            BBG02Header header = new BBG02Header();
            header.tr_code = "200201";
            header.req_no = p_req1998.reqBatchNO;
            writeCommonHeader(xmlTextWriter, header);
            xmlTextWriter.writeEndElement();//
            //拼接请求报文体
            XElement body = new XElement("body", "");
            body.addChild(new XElement("tr_acdt", DateHelper.convertD10toD8(p_req1998.bgnDate.substring(0, 10))));//交易日期
//            Map<String, Object> selMap=JDBCHelper.execQuerySingle(conn,SELECTSEQ,new Object[]{p_req1998.reqBatchNO});
//            if(selMap.size()>0){
//                body.addChild(new XElement("serial_no", selMap.get("BANKREQSEQID").toString()));//平台流水号
//            }else {
//                retAts.respCode ="-1";
//                retAts.respInfo = "批次号"+p_req1998.reqBatchNO+"未匹配对应的平台流水号";
//                retAts.writeBeforeDetail();
//                retAts.writeAfterDetail();
//                return retAts;
//            }
            body.addChild(new XElement("batch_no", p_req1998.reqBatchNO));//批次号
            body.addChild(new XElement("serial_no", ""));//平台流水号
            body.addChild(new XElement("cms_corp_no", bankFront.org));
            body.addChild(new XElement("tr_acdt", DateHelper.convertDateTimetoD8(p_req1998.bgnDate)));
            xmlTextWriter.writeXElement(body);
            xmlTextWriter.writeEndDocument();
            //发送请求报文
            String[] bankResult = sendToBank(xmlTextWriter.toXmlString(), p_req1998.reqHeader.transType, p_req1998.reqHeader.commandCode);
            //测试
            //String[] bankResult=new String[]{"","<ap><head><tr_code>200201</tr_code><cms_corp_no></cms_corp_no><user_no></user_no><req_no>PH00000BLK</req_no><serial_no>13390649</serial_no><tr_acdt>20190304</tr_acdt><tr_time>161523</tr_time><succ_flag>0</succ_flag><ret_info>交易成功</ret_info><ret_code>0000</ret_code><ext_info></ext_info><reserved></reserved><file_flag>0</file_flag><org_code></org_code><total>1</total></head><body><serial_record>seqno|acno|cur_code|acname|card_flag|amt|summary|tr_acdt|tr_time|stat|err_msg|batch_no|1|86611724101421001270|01|捷瑞物流银企直连测试账户002|0|134.00|000009AA|20190304|142854|9||304142943200|</serial_record><total>1</total><record_num>1</record_num><field_num>12</field_num><fail_count>0</fail_count><fail_amt>0.00</fail_amt><succ_count>1</succ_count><succ_amt>134.00</succ_amt></body></ap>"};
            if (bankResult[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader xmlSbReader = loadBankRespXmlReader(bankResult[1].substring(bankResult[1].indexOf("<ap>")), tmpSbMsg);
                if (xmlSbReader != null) {
                    String succFlag = xmlSbReader.getFirstText("/ap/head/succ_flag");
                    String respCode = xmlSbReader.getFirstText("/ap/head/ret_code");
                    String respInfo = xmlSbReader.getFirstText("/ap/head/ret_info");
                    String errorInfo = xmlSbReader.getFirstText("/ap/head/ext_info");
                    String fileFlag = xmlSbReader.getFirstText("/ap/head/file_flag");
                    if ("0".equals(succFlag) && "0000".equals(respCode)) {//交易成功
                        String totalNum = xmlSbReader.getFirstText("/ap/body/record_num");//总数
                        String valueNum = xmlSbReader.getFirstText("/ap/body/field_num");//字段数
                        String serial_recode = xmlSbReader.getFirstText("/ap/body/serial_record");//字段域
                        if ("0".equals(fileFlag)) {
                            if (!"0".equals(totalNum) && !"0".equals(valueNum) && !StringHelper.isNullOrEmpty(serial_recode)) {
                                //0、明细序列号|1、收款账号|2、币种(01-人民币)|3、收款户名|4、借贷标志(D-借,C-贷)|5、金额
                                //6、附言|7、交易日期|8、交易时间|9、交易状态|10、错误信息|11、批次号|
                                String[] content = serial_recode.split("\\|");
                                if (content.length == Integer.parseInt(new BigDecimal(Integer.parseInt(totalNum) + 1).multiply(new BigDecimal(valueNum)).toString())) {
                                    retAts.respCode = "0";
                                    retAts.respInfo = respInfo;
                                    retAts.reqSeqID = p_req1998.reqBatchNO;
                                    retAts.writeBeforeDetail();
                                    for (int i = 1; i < Integer.parseInt(totalNum) + 1; i++) {
                                        RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                        tmpRetDetail.payAct = p_req1998.ownAct;
                                        tmpRetDetail.payName = "";
                                        tmpRetDetail.recName = content[3 + i * Integer.parseInt(valueNum)].trim();
                                        tmpRetDetail.recAct = content[1 + i * Integer.parseInt(valueNum)].trim();
                                        tmpRetDetail.payAmount = "";
                                        tmpRetDetail.curType = convertCurToATS(content[2 + i * Integer.parseInt(valueNum)].trim());
                                        tmpRetDetail.result = respCode + "+" + content[9 + i * Integer.parseInt(valueNum)].trim();
                                        tmpRetDetail.payInfoCode = tmpRetDetail.result;
                                        tmpRetDetail.postScript = content[6 + i * Integer.parseInt(valueNum)].trim();//批内流水号
                                        tmpRetDetail.usage = content[6 + i * Integer.parseInt(valueNum)].trim();
                                        retAts.writeRetDetail(tmpRetDetail);
                                    }
                                } else {
                                    retAts.respCode = "-1";
                                    retAts.respInfo = "返回数据" + serial_recode + "异常";
                                }
                            } else {
                                retAts.respCode = "-1";
                                retAts.respInfo = respInfo + "：" + errorInfo;
                            }
                        } else if ("1".equals(fileFlag)) {
                            String fileName = xmlSbReader.getFirstText("/ap/body/file_name");//文件名
                            if (!StringHelper.isNullOrEmpty(totalNum) && !"0".equals(valueNum) && !StringHelper.isNullOrEmpty(fileName)) {
                                //下载代发结果文件
                                StringBuilder smbSb = new StringBuilder();
                                SmbFileUtil.smbDownload(trimEndFileSp(FGBiz.dspCenter.dspSet.dataDirPath + File.separator + p_req1998.reqHeader.bankCode) + File.separator, bankFront.bkTransFolder, fileName, smbSb);
                                WriteBankLogLn("下载代发结果文件" + fileName + "成功，开始处理");
                                //处理代发结果文件
                                File fileTrans = new File(trimEndFileSp(FGBiz.dspCenter.dspSet.dataDirPath + File.separator + p_req1998.reqHeader.bankCode) + File.separator + fileName);
                                if (fileTrans.exists()) {
                                    WriteBankLogLn(fileTrans.getName() + "文件存在，开始获取代发结果数据");
                                    InputStreamReader isr = new InputStreamReader(new FileInputStream(fileTrans.getPath()), getCharset());
                                    BufferedReader reader = new BufferedReader(isr);
                                    String readLine = "";
                                    int i = 1;
                                    retAts.respCode = "0";
                                    retAts.reqSeqID = p_req1998.reqBatchNO;
                                    retAts.writeBeforeDetail();
                                    while ((readLine = reader.readLine()) != null) {
                                        if (i == 1) {
                                            i++;
                                            continue;
                                        }
                                        i++;
                                        String[] content = readLine.split("\\|");
                                        if (content.length > 1) {
                                            //0、明细序列号|1、账号|2、币种(01-人民币)|3、户名|4、借贷标志(D-借,C-贷)|5、金额
                                            //6、附言|7、交易日期|8、交易时间|9、交易状态|10、错误信息|11、批次号|
                                            RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                            tmpRetDetail.payAct = p_req1998.ownAct;
                                            tmpRetDetail.payName = "";
                                            tmpRetDetail.recName = content[3];
                                            tmpRetDetail.recAct = content[1];
                                            tmpRetDetail.payAmount = content[5];
                                            tmpRetDetail.curType = convertCurToATS(content[4]);
                                            tmpRetDetail.result = respCode + "+" + content[9];
                                            tmpRetDetail.payInfoCode = tmpRetDetail.result;
                                            tmpRetDetail.postScript = content[6];//批内流水号
                                            tmpRetDetail.usage = content[6];
                                            retAts.writeRetDetail(tmpRetDetail);
                                        }
                                    }
                                    if (FileHelper.deleteFileIfExists(fileTrans.getPath())) {
                                        WriteBankLogLn("删除临时代发结果文件" + fileTrans.getName() + "成功");
                                    }
                                }
                            }
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = respInfo + "：" + errorInfo;
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = bankResult[1];
            }
        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.getMessage();
            e.printStackTrace();
        } finally {
            conn.close();
        }
        if ("-1".equals(retAts.respCode) && StringHelper.isNullOrEmpty(retAts.reqSeqID)) {
            retAts.reqSeqID = p_req1998.reqBatchNO;
        }
        if ("-1".equals(retAts.respCode)) {
            retAts.writeBeforeDetail();
        }
        retAts.writeAfterDetail();
        return retAts;
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return null;
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return null;
    }
}
